#include "fxcc/core/graph/opengl3/ImGuiGlfwApp.h"
#include "fxcc/core/graph/common/Geometry.h"
#include "fxcc/core/graph/opengl3/Resources.h"
#include "fxcc/imgui/Editor.h"

using namespace fxcc::platform;
using namespace fxcc::graph;
using namespace fxcc::graph::opengl3;
using namespace fxcc::imgui::graph::opengl3;
using BaseApp = fxcc::imgui::graph::opengl3::GlfwApp;

#undef main

struct SimpleApp : public BaseApp
{
public:
    fxcc::graph::common::Transform transform;

    std::shared_ptr<fxcc::graph::opengl3::RenderTarget> m_RenderTarget;
    std::shared_ptr<fxcc::graph::opengl3::Texture> m_Texture;

    glm::vec4 color;
    std::shared_ptr<fxcc::graph::opengl3::Effect2d> m_Effect;

    glm::vec2 aPos{ 0.0f,0.f };
    glm::vec2 aSize{ 100.f,100.0f };

    fxcc::graph::common::Camera camera;

    SimpleApp(const fxcc::platform::common::App::Desc &desc) : BaseApp(desc), color(1.0)
    {
    }
    bool Init() override
    {
        if (!BaseApp::Init())
        {
            return false;
        }

        if (!InitResources())
        {
            return false;
        }

        return true;
    };


    bool InitResources()
    {

        const auto& am = fxcc::AssertManager::Inst();
        auto& rs = fxcc::graph::opengl3::Resources::Inst();
        const auto images = rs.m_Images;

        {
            fxcc::graph::common::Texture2DDesc2 desc;
            desc.m_ImageDesc.m_hdr = false;
            desc.m_ImageDesc.m_ReqComponent = 4;
            desc.m_ImageDesc.m_Path = "D:/source/repos/fxcc/assert/toy_box_diffuse.png";
            desc.m_Mipmap = false;
            desc.m_SamplerType = fxcc::graph::common::SamplerType::_sampler_2d_default_;


            if (rs.LoadTexture(desc))
            {
                m_Texture = rs.GetTexture(desc);
            }

        }
        {
            std::string fragCode = R"(
out vec4 FragColor;
uniform sampler2D diffuseMap;

void main()
{
    FragColor=texture(diffuseMap, TexCoord);
};

)";
            m_Effect = std::make_shared<fxcc::graph::opengl3::Effect2d>(fragCode);
        }
        {
            fxcc::graph::common::RenderTargetDesc desc;
            desc.InitDesc2(1, 1200, 900, 3, false);
            m_RenderTarget = std::make_shared<fxcc::graph::opengl3::RenderTarget>(desc);

        }
        return true;
    };

    fxcc::imgui::Editor editor;
    ;

    void OnEdit() override
    {

        ImGui::Begin("Hello world");
        editor.EditInst<glm::vec2>("Pos", aPos);
        editor.EditInst<glm::vec2>("Size", aSize);
        ImGui::End();
    }
    void OnDestroy() override
    {
      
        BaseApp::OnDestroy();
    }
    void OnFrameRender() override
    {
        glViewport(0, 0, m_Desc.m_Size.x, m_Desc.m_Size.y);

        glClearColor(color.x, color.y, color.z, color.w);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // m_RenderTarget->Begin();

        m_Effect->Begin();
        m_Effect->SetScreenSize(m_Desc.m_Size.x, m_Desc.m_Size.y);

        m_Texture->Active(0);
        m_Effect->SetTransform2D(aPos, aSize);
        m_Effect->DebugQuad2();
        m_Effect->End();

 
    };

    void OnFramebuffersize(int w, int h) override
    {
        opengl3::GlfwApp::OnFramebuffersize(w, h);
        camera.SetAspect(m_Desc.Aspect());

        //{
        //	fxcc::graph::common::RenderTargetDesc desc;
        //	desc.InitDesc2(1, w, h);
        //	m_RenderTarget = std::make_shared<fxcc::graph::opengl3::RenderTarget>(desc);
        //}
    }
    void OnUpdate() override
    {
        opengl3::GlfwApp::OnUpdate();

        float ctTime = m_GlfwlTimer.m_CurrentTime;
        camera.FreeMove(m_Input, m_GlfwlTimer.m_DeltaTime);

        float deltaTime = m_GlfwlTimer.m_DeltaTime;


    }
};

int main()
{
    ztclog::pushFunction([](const ztclog::Line &line)
                         {
		if (line.m_Type != ztclog::Line::Type::_line_debug_)
		{
			std::cout << line.m_Text << std::endl;
		} });

    using _App = SimpleApp;
    using _Desc = fxcc::platform::common::App::Desc;

    _Desc desc;
    desc.m_Pos = glm::ivec2(100, 100);
    desc.m_Size = glm::ivec2(900, 600);
    desc.m_ScaleFactor = 1.0f;

    desc.m_Title = "test font";
    std::shared_ptr<_App> _app = std::make_shared<_App>(desc);
    return _app->Run();
};
